package com.app.piechart;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.Nullable;

/**
 * 扇形图：
 * 是否使用圆心 UserCenter：true、false
 */
public class PieChartView extends View {
    private static final String TAG = PieChartView.class.getSimpleName();
    private boolean mUseCenter;
    private int mStrokeWidth;
    private boolean mUseDivider;
    private int mDividerColor;
    private int mDividerAngle;
    private int mDividerWidth;
    private int mRotateAngle;

    private int mSize;
    private int mContentSize;
    private int mCenterX;
    private int mCenterY;
    private int mRadius;
    private RectF mRectF;
    private Paint mPaint;
    private int[] mColors;
    private float[] mData;
    private Paint mDividerPaint = new Paint();


    public PieChartView(Context context) {
        this(context, null);
    }

    public PieChartView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initAttrs(context, attrs);

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        if (mUseCenter) {
            mPaint.setStyle(Paint.Style.FILL);
            mDividerPaint.setStyle(Paint.Style.FILL);
        } else {
            mPaint.setStrokeWidth(mStrokeWidth);
            mPaint.setStyle(Paint.Style.STROKE);
            mDividerPaint.setStyle(Paint.Style.STROKE);
            if (mDividerAngle != 0) {
                mDividerPaint.setStrokeWidth(mStrokeWidth);
            } else {
                mDividerPaint.setStrokeWidth(mDividerWidth);
            }
        }

        mDividerPaint.setColor(mDividerColor);
        mDividerPaint.setAntiAlias(true);
        mDividerPaint.setDither(true);
    }

    private void initAttrs(Context context, AttributeSet attrs) {
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.PieChartView);
        mUseCenter = ta.getBoolean(R.styleable.PieChartView_PieChart_UseCenter, false);
        mStrokeWidth = ta.getDimensionPixelOffset(R.styleable.PieChartView_PieChart_StrokeWidth, dp2px(context, 10));
        mUseDivider = ta.getBoolean(R.styleable.PieChartView_PieChart_UseDivider, false);
        mDividerColor = ta.getColor(R.styleable.PieChartView_PieChart_DividerColor, Color.WHITE);
        mDividerAngle = ta.getInt(R.styleable.PieChartView_PieChart_DividerAngle, 0);
        mDividerWidth = ta.getDimensionPixelOffset(R.styleable.PieChartView_PieChart_DividerWidth, dp2px(context, 0));
        mRotateAngle = ta.getInt(R.styleable.PieChartView_PieChart_RotateAngle, 0);
        ta.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        mSize = Math.min(widthSize, heightSize);

        int pl = getPaddingLeft();
        int pr = getPaddingRight();
        int pt = getPaddingTop();
        int pb = getPaddingBottom();
        //大小
        int contentWidth = mSize - pl - pr;
        int contentHeight = mSize - pt - pb;
        mContentSize = Math.min(contentWidth, contentHeight);
        //圆心
        mCenterX = pl + mContentSize / 2;
        mCenterY = pt + mContentSize / 2;
        //Rect区域
        if (mRectF == null) {
            mRectF = new RectF();
        }
        int offset;

        if (mUseCenter) {
            offset = 0;
            mRadius = mContentSize / 2;
        } else {
            offset = mStrokeWidth / 2;
            mRadius = (mContentSize - mStrokeWidth) / 2;
        }
        mRectF.left = pl + offset;
        mRectF.top = pt + offset;
        mRectF.right = pl + mContentSize - offset;
        mRectF.bottom = pt + mContentSize - offset;

        setMeasuredDimension(mSize, mSize);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (mData == null || mData.length == 0) {
            return;
        }
        canvas.rotate(mRotateAngle, mCenterX, mCenterY);
        float startAngle = 0;
        for (int i = 0; i < mData.length; i++) {
            float sweepAngle = mData[i];
            mPaint.setColor(mColors[i]);
            canvas.drawArc(mRectF, startAngle, sweepAngle, mUseCenter, mPaint);
            startAngle += sweepAngle;

            if (mUseDivider) {
                if (mDividerAngle != 0) {
                    startAngle += mDividerAngle;
                }
            }
        }
        if (mUseDivider) {
            startAngle = 0;
            for (int i = 0; i < mData.length; i++) {
                float sweepAngle = mData[i];
                startAngle += sweepAngle;
                if (mDividerAngle != 0) {
                    canvas.drawArc(mRectF, startAngle, mDividerAngle, mUseCenter, mDividerPaint);
                    startAngle += mDividerAngle;
                } else {
                    int x1 = mCenterX + mRadius - mStrokeWidth / 2;
                    int y1 = mCenterY;
                    int x2 = mCenterX + mRadius + mStrokeWidth / 2;
                    int y2 = mCenterY;
                    canvas.save();
                    canvas.rotate(startAngle, mCenterX, mCenterY);
                    canvas.drawLine(x1, y1, x2, y2, mDividerPaint);
                    canvas.restore();
                }
            }
        }
    }

    /**
     * 设置数据并开始绘制
     *
     * @param weights 各部分扇形的权重。eg: [2, 2, 3]
     * @param colors  各部分扇形的颜色
     */
    public void setData(int[] weights, int[] colors) {
        if (weights.length != colors.length) {
            Log.e(TAG, "data.length must equse to colors.length");
            return;
        }
        mColors = colors;
        int totalWeight = 0;
        for (int i = 0; i < weights.length; i++) {
            totalWeight += weights[i];
        }
        float totalAngle = 360;
        if (mUseDivider) {
            totalAngle -= mDividerAngle * weights.length;
        }
        mData = new float[weights.length];
        for (int i = 0; i < weights.length; i++) {
            mData[i] = totalAngle * weights[i] / totalWeight;
        }

        for (int i = 0; i < mData.length; i++) {
            Log.e(TAG, String.valueOf(mData[i]));
        }
        invalidate();
    }

    public static int px2dp(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    public static int dp2px(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

}
